﻿using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using DG.Tweening;

public class Star : MonoBehaviour
{
    [HideInInspector]
    public GameObject normalSprite;
    [HideInInspector]
    public GameObject erasableSprite;
    [HideInInspector]
    public GameObject selectedBord;
    [HideInInspector]
    public ParticleSystem arrow;

    public int indexOfColumn;

    public int indexOfRow;
    [HideInInspector]
    public Vector3 parentSize;
    [HideInInspector]
    public Vector3 size;
    //默认图标大小，这个主要给多格宝石修正位置用
    private Vector3 oldSize;
    [HideInInspector]
    public AudioSource audioSource;
    private GameObject turnText;
    private int turn;
    public bool isCheckBoom;
    //配置文件数据
    [HideInInspector]
    public Sys_Star Data;
    private StarBox starBox;
    private int destroyCount = -1;
    public Vector3 FlyToPos { get; set; }
    [HideInInspector]
    public Animator animator;

    public bool IsCost
    {
        get
        {
            return destroyCount == 0;
        }
    }

    public int Hp
    {
        get
        {
            return destroyCount;
        }
    }

    public bool IsLastHp
    {
        get
        {
            return destroyCount == 1;
        }
    }

    void Awake()
    {
        audioSource = GetComponent<AudioSource>();
        normalSprite = transform.Find("StarBody/Normal").gameObject;
        erasableSprite = transform.Find("StarBody/Erasable").gameObject;
        selectedBord = transform.Find("StarBody/Selected").gameObject;
        arrow = transform.Find("Arrow").gameObject.GetComponent<ParticleSystem>();
        animator = transform.Find("FrameAnimation").GetComponent<Animator>();
        erasableSprite.SetActive(false);
        selectedBord.SetActive(false);
        arrow.gameObject.SetActive(false);
        starBox = GameObject.FindWithTag("StarBox").GetComponent<StarBox>();
    }

    void Update()
    {
        if (turnText)
        {
            turnText.transform.position = transform.position;
            turnText.transform.position = new Vector3(turnText.transform.position.x + oldSize.x / 2.7f, turnText.transform.position.y - oldSize.y / 2.7f, turnText.transform.position.z);

            if (!turnText.GetComponentInChildren<JumpNumber>().IsJumping)
            {
                turnText.transform.localScale = transform.localScale * 0.8f;
            }
        }
    }

    public void Init(Sys_Star starData, int row, int col)
    {
        Data = starData;
        indexOfRow = row;
        indexOfColumn = col;
        selectedBord.SetActive(false);
        SpriteRenderer normalRender = normalSprite.GetComponent<SpriteRenderer>();
        //未修改贴图前，先保存一个默认图片的尺寸
        oldSize = normalRender.bounds.size;
        normalRender.sprite = Instantiate(Resources.Load<Sprite>(starData.Image + "_1"));
        //由动画控制器控制显示，没有本体图标
        if (starData.Erasable == 2 || starData.Erasable == 3)
        {
            normalSprite.SetActive(false);
            animator.runtimeAnimatorController = Resources.Load<RuntimeAnimatorController>(starData.Image + "AMC");
        }
        //新的贴图尺寸
        size = normalRender.bounds.size;
        //必须在size与oldSize初始化后才能调用
        transform.position = RealPosition();

        FlyToPos = transform.position;
        if (Data.Type == 1) {
            FlyToPos = starBox.m_Girl.transform.position;
        }
        else if (Data.Type == 2)
        {
            FlyToPos = starBox.m_Player.transform.position;
        }

        //可以下落的宝石，才有预览被选中的效果
        //回旋针与爆炸宝石，没有这个效果
        if (starData.CanBeDropped == 1 && starData.Erasable != 2
            && starData.Erasable != 3 && starData.CreateOnTop != 1
            //只有血量为1的宝石，才有预览摧毁效果
            && starData.RequireDestroyCount == 1)
        {
            //print(starData["image"] + "_2");
            erasableSprite.GetComponent<SpriteRenderer>().sprite = Instantiate(Resources.Load<Sprite>(starData.Image + "_2"));
        }
        //1类型才有被选中图标
        if (starData.Erasable == 1)
        {
            selectedBord.GetComponent<SpriteRenderer>().sprite = Instantiate(Resources.Load<Sprite>(starData.Image + "_3"));
        }

        destroyCount = Data.RequireDestroyCount;

        //检测是否需要回合标记 
        if (Data.TurnToBoom != 0)
        {
            turnText = Instantiate(Resources.Load<GameObject>("starTurnText"));
            turnText.transform.SetParent(GameObject.FindWithTag("UINumbers").transform);
            turnText.GetComponentInChildren<Text>().text = Data.TurnToBoom.ToString();
        }

    }

    public void ChangeSortingOrder(int order)
    {
        normalSprite.GetComponent<SpriteRenderer>().sortingOrder = order;
        erasableSprite.GetComponent<SpriteRenderer>().sortingOrder = order;
        selectedBord.GetComponent<SpriteRenderer>().sortingOrder = order;
        animator.GetComponent<SpriteRenderer>().sortingOrder = order;
    }

    public void ToErasable()
    {
        if (erasableSprite.GetComponent<SpriteRenderer>().sprite)
        {
            normalSprite.SetActive(false);
            erasableSprite.SetActive(true);
        }
    }

    void ChooseShake()
    {
        if (Data.Erasable == 2 || Data.Erasable == 3)
        {
            animator.SetBool("Choose", true);
            normalSprite.SetActive(false);
        }
        else
        {
            DOTween.Kill("StarRotate" + GetHashCode());
            Sequence seq = DOTween.Sequence();
            seq.Append(transform.DORotate(new Vector3(0, 0, 20), 0.08f));
            seq.Append(transform.DORotate(new Vector3(0, 0, -20), 0.16f));
            seq.Append(transform.DORotate(Vector3.zero, 0.08f));
            seq.SetId("StarRotate" + GetHashCode());
        }

    }

    public void BoomChoose()
    {
        ChooseShake();
        ToErasable();
    }

    public void Choose(bool isErasable)
    {
        selectedBord.SetActive(true);
        ChooseShake();
        if (isErasable)
        {
            ToErasable();
        }
    }

    void CancelStandardChoose()
    {
        if (Data.Erasable == 2 || Data.Erasable == 3)
        {
            animator.SetBool("Choose", false);
        }
        else
        {
            normalSprite.SetActive(true);
        }

        erasableSprite.SetActive(false);
        arrow.gameObject.SetActive(false);
        transform.rotation = Quaternion.Euler(0, 0, 0);
        isCheckBoom = false;

    }

    public void CancelChoose()
    {
        selectedBord.SetActive(false);
        CancelStandardChoose();
    }

    public void CancelBoomChoose()
    {
        CancelStandardChoose();
    }

    public bool IsSame(Star star)
    {
        return star.indexOfRow == this.indexOfRow && star.indexOfColumn == this.indexOfColumn;
    }

    public Vector3 RealPosition()
    {
        Vector3 newPos = StarBox.bgBlocks[indexOfRow, indexOfColumn].transform.position;
        //如果是占据多个格子的宝石，要以左下角对齐修正位置 
        if (Data.Content != 1)
        {
            newPos.x += oldSize.x / 2 + 0.1f;
            //4格子，还要修正Y坐标位置
            if (Data.Content == 4)
                newPos.y += oldSize.y / 2;
            transform.position = newPos;
        }
        return newPos;
    }

    public bool IsOnPos(Vector3 pos)
    {
        Vector3 nowPos = transform.position;
        return Mathf.Abs(pos.x - nowPos.x) < 0.01f && Mathf.Abs(pos.y - nowPos.y) < 0.01f && Mathf.Abs(pos.z - nowPos.z) < 0.01f;
    }

    public IEnumerator Explode()
    {
        if (destroyCount == 0)
            yield break;
        destroyCount--;
        
        if (destroyCount == 0)
        {
            yield return StartCoroutine(FlyToDestroy());
        }
        else
        {
            //如果冰块，醉鬼的血量等于1了，则直接跳到最后一张血量的图片
            if (destroyCount == 1)
            {
                normalSprite.GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(Data.Image + "_4");
            }
            else
            {
                normalSprite.GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(Data.Image + "_" + (Data.RequireDestroyCount + 1 - destroyCount));
            }

            Sequence jumpSeq = DOTween.Sequence();
            jumpSeq.Append(normalSprite.transform.DOScale(new Vector3(1.5f, 1.5f, 1.5f), 0.1f));
            jumpSeq.Append(normalSprite.transform.DOScale(Vector3.one, 0.1f));
        }
    }

    IEnumerator FlyToDestroy()
    {
        StarBox.destroyingStarFlag++;

        if (turnText)
        {
            turnText.SetActive(false);
        }

        float flyTime = 0.5f;
        //碰撞体禁用，不能再被点击判定了
        GetComponent<BoxCollider2D>().enabled = false;

        //本体缩小，动画对象不要缩小
        Transform body = transform.Find("StarBody");
        //连接宝石没有爆炸动画，直接缩小
        if (Data.Erasable == 3)
        {
            body = transform;
        }

        //body.DOScale(new Vector3(0, 0, 0), flyTime);
        body.DOMove(FlyToPos, flyTime);

        yield return new WaitForSeconds(flyTime);

        StarBox.starTable[indexOfRow, indexOfColumn] = null;
        StarBox.destroyingStarFlag--;

        JustDestroy();
    }

    public void CrushAnimation(float time)
    {
        if (Hp > 1)
            return;

        normalSprite.SetActive(false);
        erasableSprite.SetActive(false);
        arrow.gameObject.SetActive(false);
        selectedBord.SetActive(false);

        //先保存9格坐标
        int[,] nineBlock = new int[3, 3];

        float width = oldSize.x * 100 / 3;
        float height = oldSize.y * 100 / 3;

        for (int i = 0; i < nineBlock.GetLength(0); i++)
        {
            for (int j = 0; j < nineBlock.GetLength(1); j++)
            {
                Sprite slitSprite1 = Sprite.Create(Resources.Load<Texture2D>(Data.Image + "_1"), new Rect(i * width, j * height, width - 0.01f, height - 0.01f), new Vector2(0.5f, 0.5f));
                GameObject g1 = Instantiate(Resources.Load<GameObject>("SpriteObject"));
                g1.transform.position = transform.position;
                g1.GetComponent<SpriteRenderer>().sprite = slitSprite1;

                g1.transform.DORotate(new Vector3(0, 0, Random.Range(180, 350)), time, RotateMode.FastBeyond360);
                Vector3 movePos1 = g1.transform.position;
                movePos1.x += (i - 1) * width / 50;
                movePos1.y += (j - 1) * height / 50;

                g1.transform.DOMove(movePos1, time);
                g1.GetComponent<SpriteRenderer>().DOFade(0, time).OnComplete(delegate ()
                {
                    Destroy(g1);
                });
            }
        }

    }

    public void GushAnimation(Star referenceStar, float time)
    {
        if (Hp > 1 )
            return;
        GameObject obj = Instantiate(Resources.Load<GameObject>("RigidObject"));
        obj.transform.position = transform.position;
        obj.GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(Data.Image + "_1");

        //左边
        if (indexOfColumn < referenceStar.indexOfColumn)
        {
            //随机上下
            float flag = indexOfColumn % 2 == 0 ? 1 : -1;
            obj.GetComponent<Rigidbody2D>().AddForce(new Vector2(-150, flag * 300));
        }
        else if (indexOfColumn > referenceStar.indexOfColumn)
        {
            //随机上下
            float flag = indexOfColumn % 2 == 0 ? 1 : -1;
            obj.GetComponent<Rigidbody2D>().AddForce(new Vector2(150, flag * 300));
        }
        else if (indexOfRow < referenceStar.indexOfRow)
        {
            //随机上下
            float flag = indexOfRow % 2 == 0 ? 1 : -1;
            obj.GetComponent<Rigidbody2D>().AddForce(new Vector2(flag * 150, -300));
        }
        else if (indexOfRow > referenceStar.indexOfRow)
        {
            //随机上下
            float flag = indexOfRow % 2 == 0 ? 1 : -1;
            obj.GetComponent<Rigidbody2D>().AddForce(new Vector2(flag * 150, 300));
        }

        obj.transform.DORotate(new Vector3(0, 0, 350), time, RotateMode.FastBeyond360);

        obj.GetComponent<SpriteRenderer>().DOFade(0.3f, time).OnComplete(delegate ()
        {
            Destroy(obj);
        });

    }

    public void CutSpriteAnimation(float time)
    {
        if (Data.Erasable != 1)
            return;

        normalSprite.SetActive(false);
        erasableSprite.SetActive(false);
        arrow.gameObject.SetActive(false);
        selectedBord.SetActive(false);

        for (int i = 0; i < 2; i++)
        {
            Sprite slitSprite1 = Sprite.Create(Resources.Load<Texture2D>(Data.Image + "_1"), new Rect(0, i * oldSize.y * 50, oldSize.x * 100 - 0.01f, oldSize.y * 50 - 0.01f), new Vector2(0.5f, 0.5f));
            GameObject g1 = Instantiate(Resources.Load<GameObject>("SpriteObject"));
            g1.transform.position = transform.position;
            g1.GetComponent<SpriteRenderer>().sprite = slitSprite1;

            g1.transform.DORotate(new Vector3(0, 0, Random.Range(180, 350)), time, RotateMode.FastBeyond360);
            Vector3 movePos1 = g1.transform.position;
            if (i == 0)
                movePos1.x -= Random.Range(0.5f, 1f);
            else
                movePos1.x += Random.Range(0.5f, 1f);
            movePos1.y += (Random.Range(-1f, 1f));
            g1.transform.DOMove(movePos1, time);
            g1.GetComponent<SpriteRenderer>().DOFade(0, time).OnComplete(delegate ()
            {
                Destroy(g1);
            });
        }
    }

    public void JustDestroy()
    {
        //食材宝石，要减去已有的数量
        if (starBox.ColorCount.ContainsKey(Data.Id))
            starBox.ColorCount[Data.Id]--;
        if (gameObject)
            Destroy(gameObject);
        if (turnText)
            Destroy(turnText);
    }

    public IEnumerator Fall()
    {
        if (IsOnPos(RealPosition()))
        {
            yield break;
        }
        StarBox.fallingStarFlag++;
        Sequence fallTWeen = DOTween.Sequence();
        fallTWeen.Append(transform.DOMove(RealPosition(), 0.3f));
        fallTWeen.Play();
        yield return fallTWeen.WaitForCompletion();
        //果冻效果不能计算入协程中，否则会震动0.6s内无法点击，大大延长了禁止点击的时间
        //transform.DOShakeScale(0.6f, 0.5f, 10, 90);
        StarBox.fallingStarFlag--;
    }

    public IEnumerator ChangeTurn()
    {
        StarBox.checkingStarTurnFlag++;
        if (turn > 0)
        {
            turn--;
            if (turnText)
            {
                turnText.GetComponentInChildren<Text>().text = turn.ToString();
            }

            if (turn == 0)
            {
                turnText.SetActive(false);

                //下落型，回合到了，会自动消失
                if (Data.IsTurnToDestroy != 0)
                {
                    StartCoroutine(Explode());
                }
                //其他类型的宝石，回合到了，会轮询回去，
                else
                {
                    turnText.SetActive(true);
                    turnText.GetComponentInChildren<Text>().text = Data.TurnToBoom.ToString();
                }
            }
        }
        StarBox.checkingStarTurnFlag--;
        yield return null;
    }

}
